/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package clientudp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;

/**
 *
 * @author Minh
 */
public class ClientUDP {

    public  ArrayList<String> readAndFragment(String SourceFileName, int CHUNK_SIZE) throws IOException {
//log ("File Is Reading "+ SourceFileName );
        File willBeRead = new File(SourceFileName);
        int FILE_SIZE = (int) willBeRead.length();
        ArrayList<String> nameList = new ArrayList<String>();

        System.out.println("Total File Size: " + FILE_SIZE);

        int NUMBER_OF_CHUNKS = 0;
        byte[] temporary = null;

        try {
            InputStream inStream = null;
            int totalBytesRead = 0;

            try {
                inStream = new BufferedInputStream(new FileInputStream(willBeRead));

                while (totalBytesRead < FILE_SIZE) {
                    String PART_NAME = "data" + NUMBER_OF_CHUNKS + ".bin";
                    int bytesRemaining = FILE_SIZE - totalBytesRead;
                    if (bytesRemaining < CHUNK_SIZE) // Remaining Data Part is Smaller Than CHUNK_SIZE
                    // CHUNK_SIZE is assigned to remain volume
                    {
                        CHUNK_SIZE = bytesRemaining;
                        System.out.println("CHUNK_SIZE: " + CHUNK_SIZE);
                    }
                    temporary = new byte[CHUNK_SIZE]; //Temporary Byte Array
                    int bytesRead = inStream.read(temporary, 0, CHUNK_SIZE);

                    if (bytesRead > 0) // If bytes read is not empty
                    {
                        totalBytesRead += bytesRead;
                        NUMBER_OF_CHUNKS++;
                    }

                    write(temporary, PART_NAME);
                    nameList.add(PART_NAME);
                    System.out.println("Total Bytes Read: " + totalBytesRead);
                }

            } finally {
                inStream.close();
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return nameList;
    }

    void write(byte[] DataByteArray, String DestinationFileName) {
        try {
            OutputStream output = null;
            try {
                output = new BufferedOutputStream(new FileOutputStream(DestinationFileName));
                output.write(DataByteArray);
                System.out.println("Writing Process Was Performed");
            } finally {
                output.close();
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void mergeParts(ArrayList<String> nameList, String DESTINATION_PATH) {
        File[] file = new File[nameList.size()];
        byte AllFilesContent[] = null;

        int TOTAL_SIZE = 0;
        int FILE_NUMBER = nameList.size();
        int FILE_LENGTH = 0;
        int CURRENT_LENGTH = 0;

        for (int i = 0; i < FILE_NUMBER; i++) {
            file[i] = new File(nameList.get(i));
            TOTAL_SIZE += file[i].length();
        }

        try {
            AllFilesContent = new byte[TOTAL_SIZE]; // Length of All Files, Total Size
            InputStream inStream = null;

            for (int j = 0; j < FILE_NUMBER; j++) {
                inStream = new BufferedInputStream(new FileInputStream(file[j]));
                FILE_LENGTH = (int) file[j].length();
                inStream.read(AllFilesContent, CURRENT_LENGTH, FILE_LENGTH);
                CURRENT_LENGTH += FILE_LENGTH;
                inStream.close();
            }

        } catch (FileNotFoundException e) {
            System.out.println("File not found " + e);
        } catch (IOException ioe) {
            System.out.println("Exception while reading the file " + ioe);
        } finally {
            write(AllFilesContent, DESTINATION_PATH);
        }

        System.out.println("Merge was executed successfully.!");

    }
    public static String generateBufferedHash(String file)
	throws NoSuchAlgorithmException,
	FileNotFoundException, IOException {
 
	MessageDigest md = MessageDigest.getInstance("MD5");
 
	InputStream is= new FileInputStream(file);
 
	byte[] buffer=new byte[8192];
        int read=0;
 
        while( (read = is.read(buffer)) > 0)
                md.update(buffer, 0, read);
 
        byte[] md5 = md.digest();
        BigInteger bi=new BigInteger(1, md5);
 
        return bi.toString(16);
    }  
    public static void main(String[] args) throws IOException, NoSuchAlgorithmException  {
        // TODO code application logic here
        // Client Program
         ClientUDP c=new ClientUDP();
         ArrayList<String> nameList=c.readAndFragment("baocao.docx", 512);
       
         c.mergeParts(nameList,"C:\\a.docx");
         String exam=generateBufferedHash("baocao.docx");
         System.out.println(exam);
        try{
            String stSend;
            String stRcv;
            boolean sExit,rExit;
            //khoi tao socket
            DatagramSocket socket =new DatagramSocket();
            int port = 1234;
            //Gan dia chi IP va port vao InetAddress
            //InetAddress ipServer= InetAddress.getByName("localhost");
            InetAddress ipServer = InetAddress.getByAddress("127.0.0.1", new byte[]{127, 0, 0, 1});
           
                //Goi thong diep cho Server
                byte []sendData = new byte[1024];
                BufferedReader in =new BufferedReader(new InputStreamReader(System.in) );
                System.out.print("Client: ");
               // stSend = in.readLine();
                sendData = exam.getBytes();
                //Khoi tao DatagramPacket
                DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,ipServer,port);
                //Send DatagramPacket
                socket.send(sendPacket);
                //Nhan thong diep tu Server
                byte []rcvbuf = new byte[1024];
                //Khoi tao DatagramPacket de nhan data
//                DatagramPacket rcvpkt = new DatagramPacket(rcvbuf,rcvbuf.length);
//                //Goi ham nhan data
//                socket.receive(rcvpkt);
//                stRcv = new String(rcvpkt.getData(),0,rcvpkt.getLength());
//                System.out.println("Server: "+ stRcv);

             
            //dong DatagramSocket
            socket.close();
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
}
